<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Babylon.js GUI 坐标计算演示</title>
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.babylonjs.com/gui/babylon.gui.min.js"></script>
    <style>
        body, html {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            background-color: #f0f0f0;
        }
        canvas {
            width: 100%;
            height: 100%;
            touch-action: none;
        }
        .controls {
            position: absolute;
            top: 10px;
            left: 10px;
            background-color: rgba(255, 255, 255, 0.8);
            padding: 10px;
            border-radius: 5px;
            z-index: 100;
        }
        button {
            margin: 5px;
            padding: 5px 10px;
        }
        pre {
            background-color: #f5f5f5;
            padding: 10px;
            border-radius: 5px;
            overflow-x: auto;
            max-width: 500px;
        }
        .zoom-info {
            position: absolute;
            bottom: 10px;
            left: 10px;
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 5px 10px;
            border-radius: 3px;
            font-size: 14px;
            z-index: 100;
        }
    </style>
</head>
<body>
    <div class="controls">
        <button id="logCoordinatesBtn">打印坐标信息</button>
        <pre id="coordinatesOutput"></pre>
    </div>
    <div class="zoom-info" id="zoomInfo">缩放比例: 1.00</div>
    <canvas id="renderCanvas"></canvas>

    <script>
        // 创建场景
        const canvas = document.getElementById('renderCanvas');
        const engine = new BABYLON.Engine(canvas, true);
        const scene = new BABYLON.Scene(engine);
        
        // 添加摄像机
        const camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 5, BABYLON.Vector3.Zero(), scene);
        camera.attachControl(canvas, true);
        
        // 添加光源
        const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
        light.intensity = 0.7;
        
        // 创建GUI
        const advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
        
        // 创建根容器
        const rootContainer = new BABYLON.GUI.StackPanel("rootContainer");
        rootContainer.width = "80%";
        rootContainer.height = "80%";
        rootContainer.background = "rgba(200, 200, 200, 0.5)";
        rootContainer.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
        rootContainer.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER;
        advancedTexture.addControl(rootContainer);
        
        // 绘制坐标系
        function drawCoordinateSystem(container) {
            // 原点
            const originLabel = new BABYLON.GUI.Ellipse();
            originLabel.width = '5px';
            originLabel.height = '5px';
            originLabel.background = "lime";
            originLabel.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
            originLabel.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER;
            container.addControl(originLabel);
        }
        
        // 绘制根容器中的坐标系
        drawCoordinateSystem(rootContainer);
        
        // 创建中间容器
        const middleContainer = new BABYLON.GUI.StackPanel("middleContainer");
        middleContainer.width = "70%";
        middleContainer.height = "70%";
        middleContainer.background = "rgba(150, 150, 255, 0.5)";
        middleContainer.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
        middleContainer.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER;
        // 初始缩放比例
        middleContainer.scaleX = 1.0;
        middleContainer.scaleY = 1.0;
        rootContainer.addControl(middleContainer);
        
        // 绘制中间容器中的坐标系
        drawCoordinateSystem(middleContainer);
        
        // 创建目标控件
        const targetControl = new BABYLON.GUI.Rectangle("targetControl");
        targetControl.width = "150px";
        targetControl.height = "100px";
        targetControl.background = "red";
        targetControl.thickness = 2;
        targetControl.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
        targetControl.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
        targetControl.left = "20px";
        targetControl.top = "30px";
        middleContainer.addControl(targetControl);
        
        // 创建标签显示控件
        const label = new BABYLON.GUI.TextBlock();
        label.text = "目标控件";
        label.color = "white";
        label.fontSize = 16;
        targetControl.addControl(label);
        
        // 创建一个参考点，用于演示坐标计算
        const referencePoint = new BABYLON.GUI.Ellipse("referencePoint");
        referencePoint.width = "10px";
        referencePoint.height = "10px";
        referencePoint.background = "green";
        referencePoint.thickness = 0;
        middleContainer.addControl(referencePoint);
        // referencePoint.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
        // referencePoint.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
        
        // 核心功能：获取控件在指定容器中的相对坐标（考虑缩放）
        // point参数：相对于control的点，默认为左上角(0,0)
        function getPoint(container, control, point = { x: 0, y: 0 }) {
            let x = point.x;
            let y = point.y;
            let current = control;

            while (current && current !== container) {
                // Apply scale
                const scaleX = current.scaleX ?? 1;
                const scaleY = current.scaleY ?? 1;
                x *= scaleX;
                y *= scaleY;

                // Apply rotation (around top-left)
                const rotation = current.rotation ?? 0;
                if (rotation !== 0) {
                    const cos = Math.cos(rotation);
                    const sin = Math.sin(rotation);
                    const rx = x * cos - y * sin;
                    const ry = x * sin + y * cos;
                    x = rx;
                    y = ry;
                }

                // Add control's offset within its parent
                if (current._currentMeasure) {
                    x += current._currentMeasure.left;
                    y += current._currentMeasure.top;
                }

                // Step up the parent chain
                current = current.parent;
                if (!current) break; // Safety
                // Now, (x, y) are in parent's space, continue
                // If current === container, stop
            }

            if (current !== container) {
                // container is not an ancestor of control!
                console.log("The specified container is not an ancestor of the control.");
                return {x: 0, y:0};
            }

            return {x, y};
            // // 获取控件相对于其父容器的坐标
            // let pointInContainer = { x: point.x, y: point.y };
            // let currentControl = control;
            // let offsetX = 0;
            // let offsetY = 0;
            // let found = currentControl === container;
            // while (!found && currentControl.parent) {
            //     const currentWidth = currentControl.widthInPixels * currentControl.parent.scaleX;
            //     const currentHeight = currentControl.heightInPixels * currentControl.parent.scaleY;
            //     const parentWidth = currentControl.parent.widthInPixels * (currentControl.parent.parent? currentControl.parent.parent.scaleX : 1);
            //     const parentHeight = currentControl.parent.heightInPixels * (currentControl.parent.parent? currentControl.parent.parent.scaleY : 1);

            //     // 考虑对齐方式
            //     if (currentControl.parent.horizontalAlignment === BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER) {
            //         offsetX = parentWidth + currentControl.leftInPixels;
            //     } else if (currentControl.horizontalAlignment === BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT) {
            //         offsetX = parentWidth - currentWidth;
            //     } else {
            //         offsetX += currentControl.leftInPixels * currentControl.parent.scaleX;
            //     }
                
            //     if (currentControl.verticalAlignment === BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER) {
            //         offsetY = (parentHeight - currentHeight) / 2;
            //     } else if (currentControl.verticalAlignment === BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM) {
            //         offsetY = parentHeight - currentHeight;
            //     } else {
            //         offsetY += currentControl.topInPixels * currentControl.parent.scaleY;
            //     }
                
            //     // 移动到父容器
            //     found = currentControl === container;
            //     currentControl = currentControl.parent;
            // }

            // if(!found) {
            //     return null;
            // }
            
            // pointInContainer = { x: pointInContainer.x + offsetX, y: pointInContainer.y + offsetY };
            // return pointInContainer;
        }
        
        // 添加鼠标滚轮缩放功能
        let currentScale = 1.0;
        const minScale = 0.5;
        const maxScale = 2.0;
        const scaleStep = 0.1;
        
        // 更新缩放信息显示
        function updateZoomInfo() {
            document.getElementById('zoomInfo').textContent = `缩放比例: ${currentScale.toFixed(2)}`;
        }
        
        // 鼠标滚轮事件处理
        canvas.addEventListener('wheel', function(e) {
            e.preventDefault();
            
            // 根据滚轮方向调整缩放比例
            if (e.deltaY < 0) {
                // 向上滚动，放大
                currentScale = Math.min(currentScale + scaleStep, maxScale);
            } else {
                // 向下滚动，缩小
                currentScale = Math.max(currentScale - scaleStep, minScale);
            }
            
            // 应用新的缩放比例
            middleContainer.scaleX = currentScale;
            middleContainer.scaleY = currentScale;
            
            // 更新缩放信息显示
            updateZoomInfo();
        });
        
        // 初始化显示
        updateZoomInfo();
        
        // 按钮点击事件
        document.getElementById('logCoordinatesBtn').addEventListener('click', function() {
            // 计算目标控件左上角在中间容器中的坐标
            const topLeftInMiddleContainer = getPoint(middleContainer, targetControl, {x: 0, y: 0});
            
            // 计算目标控件中心点在中间容器中的坐标
            const centerInMiddleContainer = getPoint(middleContainer, targetControl, { 
                x: targetControl.widthInPixels / 2 * targetControl.parent.scaleX, 
                y: targetControl.heightInPixels / 2 * targetControl.parent.scaleY
            });
            
            // 计算目标控件左上角在根容器中的坐标
            const topLeftInRootContainer = getPoint(rootContainer, targetControl, {x: 0, y: 0});
            
            // 计算目标控件中心点在根容器中的坐标
            const centerInRootContainer = getPoint(rootContainer, targetControl, { 
                x: targetControl.widthInPixels / 2 * targetControl.parent.scaleX, 
                y: targetControl.heightInPixels / 2 * targetControl.parent.scaleY
            });
            
            // 更新参考点位置到目标控件左上角（在中间容器中）
            referencePoint.left = topLeftInMiddleContainer.left + "px";
            referencePoint.top = topLeftInMiddleContainer.top + "px";
            
            // 显示坐标信息
            const outputElement = document.getElementById('coordinatesOutput');
            outputElement.textContent = `
- 目标父容器HA: ${targetControl.parent.horizontalAlignment}, VA: ${targetControl.parent.verticalAlignment}
- 目标空间中心点 X: ${targetControl.centerX}px, Y: ${targetControl.centerY}px

- 目标空间左上角 X: ${targetControl.leftInPixels}px, Y: ${targetControl.topInPixels}px
目标控件在中间容器中的坐标：
- 左上角 X: ${topLeftInMiddleContainer.x.toFixed(2)}px, Y: ${topLeftInMiddleContainer.y.toFixed(2)}px
- 中心点 X: ${centerInMiddleContainer.x.toFixed(2)}px, Y: ${centerInMiddleContainer.y.toFixed(2)}px

目标控件在根容器中的坐标：
- 左上角 X: ${topLeftInRootContainer.x.toFixed(2)}px, Y: ${topLeftInRootContainer.y.toFixed(2)}px
- 中心点 X: ${centerInRootContainer.x.toFixed(2)}px, Y: ${centerInRootContainer.y.toFixed(2)}px

容器信息：
- 根容器宽度: ${rootContainer.widthInPixels}px
- 根容器高度: ${rootContainer.heightInPixels}px
- 中间容器宽度: ${middleContainer.widthInPixels}px
- 中间容器高度: ${middleContainer.heightInPixels}px
- 目标控件宽度: ${targetControl.widthInPixels}px
- 目标控件高度: ${targetControl.heightInPixels}px
- 中间容器缩放比例: ${currentScale.toFixed(2)}`;
        });
        
        // 渲染循环
        engine.runRenderLoop(() => {
            scene.render();
        });
        
        // 响应窗口大小变化
        window.addEventListener('resize', () => {
            engine.resize();
        });
    </script>
</body>
</html>    